<script setup lang="ts">
import { ref, nextTick, onMounted, onUnmounted } from 'vue';
import { Edit } from '@element-plus/icons-vue';

const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: ''
  },
  placeholder: {
    type: String,
    default: '双击选择'
  },
  // 下拉选项
  options: {
    type: Array as () => { label: string; value: string | number }[],
    default: () => []
  }
});

const emit = defineEmits(['update:modelValue', 'change']);

const isEditing = ref(false);
const selectValue = ref<any>('');
const selectRef = ref();

const startEdit = () => {
  isEditing.value = true;
  selectValue.value = props.modelValue || '';
  nextTick(() => {
    const select = selectRef.value;
    if (!select) return;
    // 聚焦
    select.focus?.();
    // 展开下拉
    select.toggleMenu?.(true);
  });
};

const save = () => {
  emit('update:modelValue', selectValue.value);
  emit('change', selectValue.value);
  isEditing.value = false;
};

const cancel = () => {
  isEditing.value = false;
};

const handleClickOutside = (e) => {
  if (selectRef.value?.$el?.contains(e.target)) return;
  const cell = e.target.closest('.editable-cell');
  if (cell) return;
  if (isEditing.value) cancel();
};

onMounted(() => {
  document.addEventListener('click', handleClickOutside);
});
onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside);
});
</script>

<template>
  <div class="editable-cell" @click="startEdit" @click.stop>
    <!-- 显示模式 -->
    <template v-if="!isEditing">
      <span class="cell-text" v-if="props.options.find((opt) => opt.value === modelValue)?.label">
        {{ props.options.find((opt) => opt.value === modelValue)?.label }}
      </span>
      <span class="cell-text no-select" v-else> 未选择 </span>
      <el-icon class="edit-hint">
        <Edit />
      </el-icon>
    </template>

    <!-- 编辑模式 -->
    <template v-else>
      <el-select
        ref="selectRef"
        v-model="selectValue"
        placeholder="请选择"
        size="small"
        style="width: 100%"
        @change="save"
        @blur="cancel"
        @click.stop
      >
        <el-option
          v-for="opt in props.options"
          :key="opt.value"
          :label="opt.label"
          :value="opt.value"
        />
      </el-select>
    </template>
  </div>
</template>

<style scoped>
.editable-cell {
  padding: 2px 6px;
  min-height: 24px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  border-radius: 3px;
  transition: background-color 0.2s;
  width: 100%;
}

.editable-cell:hover {
  background-color: #f7f7f7;
}

.cell-text {
  color: #333;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.no-select {
  color: #999;
}

.edit-hint {
  font-size: 14px;
  color: #999;
  opacity: 0.6;
  transition: opacity 0.2s;
}

.editable-cell:hover .edit-hint {
  opacity: 1;
  color: #409eff;
}
</style>
